package com.weijian.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.weijian.common.enums.GlobalErrorCodeConstants;
import com.weijian.common.enums.RedisConstants;
import com.weijian.common.exception.ServiceException;
import com.weijian.common.pojo.CommonResult;
import com.weijian.dal.dto.OrderDetailDTO;
import com.weijian.dal.entity.Item;
import com.weijian.mapper.ItemMapper;
import com.weijian.service.ItemService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.aop.framework.AopContext;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 商品表 服务实现类
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class ItemServiceImpl extends ServiceImpl<ItemMapper, Item> implements ItemService {

    final StringRedisTemplate stringRedisTemplate;

    final ItemMapper itemMapper;

    @Override
    public void deductStock(List<OrderDetailDTO> items) {
        List<Item> itemList = items.stream()
                .map(dto -> {
                    Integer stock = getById(dto.getItemId()).getStock();
                    stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + dto.getItemId());
                    return Item.builder()
                            .id(dto.getItemId())
                            .stock(stock - dto.getNum())
                            .build();
                })
                .toList();
        log.info("商品：{}", itemList.get(0).getId());
        log.info("商品：{}", itemList.get(0).getStock());
        ItemService proxy = (ItemService) AopContext.currentProxy();
        if (!proxy.updateBatchById(itemList)) {
            throw new ServiceException(400, "库存扣减失败，可能是库存不足");
        }
    }

   /* @Override
    public void deductStock(List<OrderDetailDTO> items) {
        List<Item> itemList = new ArrayList<>();
        for (OrderDetailDTO dto : items) {
            Item item = getById(dto.getItemId());
            if (item.getStock() < dto.getNum()) {
                throw new ServiceException(400, "库存不足");
            }
            item.setStock(item.getStock() - dto.getNum());
            itemList.add(item);
        }
        log.info("商品：{}", itemList.get(0).getId());

        int count = 0;
        try {
            count = itemMapper.deductStockBatch(itemList);
        } catch (Exception e) {
            log.error("库存扣减失败，可能是库存不足", e);
            throw new RuntimeException(e);
        }
        log.info("商品数量:{}", count);
        if (count != 1) {
            throw new ServiceException(400, "库存扣减失败");
        }
    }*/


    @Override
    public CommonResult<Item> queryItemById(Long id) {
        String itemKey = RedisConstants.CACHE_SHOP_KEY + id;
        String itemJson = stringRedisTemplate.opsForValue().get(itemKey);
        log.info("商品：{}", itemJson);
        if (itemJson != null) {
            return CommonResult.success(JSONUtil.toBean(itemJson, Item.class));
        }
        Item item = getById(id);
        if (item == null) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }
        stringRedisTemplate.opsForValue().set(itemKey, JSONUtil.toJsonStr(item));
        return CommonResult.success(item);
    }

    @Override
    public CommonResult<List<Item>> queryItemByIds(List<Long> ids) {
        List<Item> cachedItems = new ArrayList<>();
        List<Long> missingIds = new ArrayList<>();
        // 1. 先尝试从 Redis 获取商品，并识别缺失的商品 ID
        for (Long id : ids) {
            String itemKey = RedisConstants.CACHE_SHOP_KEY + id;
            String itemJson = stringRedisTemplate.opsForValue().get(itemKey);
            if (itemJson != null) {
                cachedItems.add(JSONUtil.toBean(itemJson, Item.class));
            } else {
                missingIds.add(id);
            }
        }
        log.info("redis获取商品数量：{}", cachedItems.size());
        // 2. 如果 Redis 中已找到全部商品，则直接返回
        if (cachedItems.size() == ids.size()) {
            return CommonResult.success(cachedItems);
        }
        // 3. 查询数据库补全缺失商品
        List<Item> dbItems = listByIds(missingIds);
        if (dbItems.isEmpty()) {
            return CommonResult.error(GlobalErrorCodeConstants.NOT_FOUND);
        }
        // 4. 将数据库查询结果写入 Redis 缓存
        dbItems.forEach(item -> {
            String itemKey = RedisConstants.CACHE_SHOP_KEY + item.getId();
            stringRedisTemplate.opsForValue().set(itemKey, JSONUtil.toJsonStr(item));
        });
        // 5. 合并缓存和数据库数据
        cachedItems.addAll(dbItems);
        return CommonResult.success(cachedItems);
    }

    @Override
    public void updateItem(Item item) {
        if (item.getId() == null) {
            throw new ServiceException(400, "商品为空");
        }
        log.info("更新商品：{}", item);
        updateById(item);
        stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + item.getId());
    }

    @Override
    public void deleteItemById(Long id) {
        boolean remove = removeById(id);
        if (!remove) {
            throw new ServiceException(400, "删除商品失败");
        }
        stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + id);
    }
}
